//
//  ARButton.m
//  AwesomeRecorder
//
//  Created by Xing on 2019/11/29.
//  Copyright © 2019 Xing. All rights reserved.
//

#import "ARButton.h"

#define DEFAULT_TITLE_COLOR (G_Color_Black)

@implementation ARButton {
    
    UIImageView *_imageView;
    
    NSMutableDictionary *_images;
    
    UIView *_backgroundView;
    
    NSMutableDictionary *_bgColors;
    
    UILabel *_titleLabel;
    
    NSMutableDictionary *_titles;
    
    NSMutableDictionary *_titleColors;
    
    BOOL _enable;
}

+ (instancetype) buttonWithType:(UIButtonType)buttonType {
    
    return [super buttonWithType:UIButtonTypeCustom];
}

- (instancetype) init {
    
    return [self initWithFrame:CGRectZero];
}

- (instancetype) initWithFrame:(CGRect)frame {
    
    self = [super initWithFrame:frame];
    
    if (self) {
        
        [self initSelf];
    }
    
    return self;
}

- (void) initSelf {
    
    self.tintColor = [UIColor clearColor];
    
    self.adjustsImageWhenHighlighted = NO;
    
    _enable = YES;
    
    _bgColors = [NSMutableDictionary dictionary];
    
    _images = [NSMutableDictionary dictionary];
    
    _titles = [NSMutableDictionary dictionary];
    
    _titleColors = [NSMutableDictionary dictionary];
    [_titleColors setObject:[UIColor blackColor] forKey:[self keyForState:UIControlStateNormal]];
    
    _backgroundRect = self.bounds;
    _backgroundView = [[UIView alloc] initWithFrame:self.bounds];
    _backgroundView.backgroundColor = [UIColor clearColor];
    _backgroundView.userInteractionEnabled = NO;
    [self addSubview:_backgroundView];
    
    _imageView = [[UIImageView alloc] initWithFrame:self.bounds];
    _imageView.contentMode = UIViewContentModeScaleAspectFit;
    _imageView.backgroundColor = [UIColor clearColor];
    [self addSubview:_imageView];
    
    [self setValue:_imageView forKey:@"imageView"];
    
    _titleLabel = [[UILabel alloc] initWithFrame:self.bounds];
    _titleLabel.backgroundColor = [UIColor clearColor];
    _titleLabel.textColor = [UIColor blackColor];
    [self addSubview:_titleLabel];
    
    [self setValue:_titleLabel forKey:@"titleLabel"];
}

- (UILabel *) titleLabel {
    
    return _titleLabel;
}

- (UIImageView *) imageView {
    
    return _imageView;
}

- (void) setTitleRect:(CGRect)titleRect {
    
    _titleRect = titleRect;
    _titleLabel.frame = titleRect;
}

- (void) setImageRect:(CGRect)imageRect {
    
    _imageRect = imageRect;
    _imageView.frame = imageRect;
}

- (void) setBackgroundRect:(CGRect)backgroundRect {
    
    _backgroundRect = backgroundRect;
    _backgroundView.frame = backgroundRect;
}

//==========

- (void) setBackgroundColor:(UIColor *)backgroundColor forState:(UIControlState)state {
    
    if(state == UIControlStateNormal) {
        
        [self changeBackgroundViewColor:backgroundColor];
    }
    
    if (self.state == state || (!_enable && state==UIControlStateDisabled)) {
        
        [self changeBackgroundViewColor:backgroundColor];
    }
    
    [_bgColors setValue:backgroundColor forKey:[self keyForState:state]];
}

- (void) setImage:(UIImage *)image forState:(UIControlState)state {
    
    if (state == UIControlStateNormal) {
        
        _imageView.image = image;
    }
    
    if (self.state == state || (!_enable && state==UIControlStateDisabled)) {
        
        _imageView.image = image;
    }
    
    if (image) {
        
        [_images setValue:image forKey:[self keyForState:state]];
    }
}

- (void) setTitle:(NSString *)title forState:(UIControlState)state {
    
    title = title?title:@"";
    
    if (state == UIControlStateNormal) {
        
        [_titleLabel setText:title];
    }
    
    if (self.state == state || (!_enable && state==UIControlStateDisabled)) {
        
        [_titleLabel setText:title];
    }
    
    [_titles setObject:title forKey:[self keyForState:state]];
}

- (void) setTitleColor:(UIColor *)color forState:(UIControlState)state {
    
    if (state == UIControlStateNormal) {
        
        [_titleLabel setTextColor:color];
    }
    
    if (self.state == state || (!_enable && state==UIControlStateDisabled)) {
        
        [_titleLabel setTextColor:color];
    }
    
    [_titleColors setObject:color forKey:[self keyForState:state]];
}

- (void) changeBackgroundViewColor:(UIColor *)color {
    
    @synchronized (_backgroundView) {
        
        [_backgroundView setBackgroundColor:color];
        [self sendSubviewToBack:_backgroundView];
    }
    
}

//==========

- (UIImage *) imageForState:(UIControlState)state {
    
    UIImage *img = [_images valueForKey:[self keyForState:state]];
    
    if (!img && state != UIControlStateNormal) {
        
        UIImage *normalImg = [_images valueForKey:[self keyForState:UIControlStateNormal]];
        
        if (state == UIControlStateHighlighted) {
            
            if (normalImg) {
                
                img = [self grayImage:normalImg];
                [_images setValue:img forKey:[self keyForState:UIControlStateHighlighted]];
            }
        }else{
            
            img = normalImg;
        }
        
    }
    
    return img;
}

- (NSString *) titleForState:(UIControlState)state {
    
    NSString *title = [_titles valueForKey:[self keyForState:state]];
    
    if (!title && state != UIControlStateNormal) {
        
        title = [_titles valueForKey:[self keyForState:UIControlStateNormal]];
    }
    
    return title;
}

- (UIColor *) titleColorForState:(UIControlState)state {
    
    UIColor *color = [_titleColors valueForKey:[self keyForState:state]];
    
    if (!color && state != UIControlStateNormal) {
        
        if (state == UIControlStateDisabled) {
            
            color = [UIColor lightGrayColor];
            [_titleColors setValue:color forKey:[self keyForState:state]];
            
        }else{
            
            color = [_titleColors valueForKey:[self keyForState:UIControlStateNormal]];
        }
    }
    
    return color;
}

- (UIColor *) backgroundColorForState:(UIControlState)state {
    
    UIColor *color = [_bgColors valueForKey:[self keyForState:state]];
    
    if (!color) {
        
        if (state != UIControlStateNormal) {
            
            color = [_bgColors valueForKey:[self keyForState:UIControlStateNormal]];
        }else{
            
            color = [UIColor clearColor];
        }
    }
    
    return color;
}

//==========

- (void) setEnabled:(BOOL)enable {
    
    if (enable == _enable) {
        
        return;
    }
    
    _enable = enable;
    
    if (enable) {
        
        self.userInteractionEnabled = YES;
        
        [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateNormal]];
        
        [_imageView setImage:[self imageForState:UIControlStateNormal]];
        
        [_titleLabel setText:[self titleForState:UIControlStateNormal]];
        
        [_titleLabel setTextColor:[self titleColorForState:UIControlStateNormal]];
        
    } else {
        
        self.userInteractionEnabled = NO;
        
        [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateDisabled]];
        
        [_imageView setImage:[self imageForState:UIControlStateDisabled]];
        
        [_titleLabel setText:[self titleForState:UIControlStateDisabled]];
        
        [_titleLabel setTextColor:[self titleColorForState:UIControlStateDisabled]];
    }
}

- (BOOL) isEnabled {
    
    return _enable;
}

- (void) setHighlighted:(BOOL)highlighted {
    
    [super setHighlighted:highlighted];
    
    if (highlighted) {
        
        [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateHighlighted]];
        
        [_imageView setImage:[self imageForState:UIControlStateHighlighted]];
        
        [_titleLabel setText:[self titleForState:UIControlStateHighlighted]];
        
        [_titleLabel setTextColor:[self titleColorForState:UIControlStateHighlighted]];
        
    } else {
        
        // 由于系统在调用setSelected后，会再触发一次setHighlighted，故做如下处理，否则，背景色会被最后一次的覆盖掉。
        if ([self isSelected]) {
            
            [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateSelected]];
            
            [_imageView setImage:[self imageForState:UIControlStateSelected]];
            
            [_titleLabel setText:[self titleForState:UIControlStateSelected]];
            
            [_titleLabel setTextColor:[self titleColorForState:UIControlStateSelected]];
            
        } else {
            
            [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateNormal]];
            
            [_imageView setImage:[self imageForState:UIControlStateNormal]];
            
            [_titleLabel setText:[self titleForState:UIControlStateNormal]];
            
            [_titleLabel setTextColor:[self titleColorForState:UIControlStateNormal]];
        }
    }
}

- (void) setBackgroundColor:(UIColor *)backgroundColor {
    
    [super setBackgroundColor:backgroundColor];
    [self setBackgroundColor:backgroundColor forState:UIControlStateNormal];
}

- (void) setSelected:(BOOL)selected {
    
    [super setSelected:selected];
    
    if (selected) {
        
        [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateSelected]];
        
        [_imageView setImage:[self imageForState:UIControlStateSelected]];
        
        [_titleLabel setText:[self titleForState:UIControlStateSelected]];
        
        [_titleLabel setTextColor:[self titleColorForState:UIControlStateSelected]];
        
    }else{
        
        [self changeBackgroundViewColor:[self backgroundColorForState:UIControlStateNormal]];
        
        [_imageView setImage:[self imageForState:UIControlStateNormal]];
        
        [_titleLabel setText:[self titleForState:UIControlStateNormal]];
        
        [_titleLabel setTextColor:[self titleColorForState:UIControlStateNormal]];
    }
}

- (NSString *)keyForState:(UIControlState)state {
    
    return [NSString stringWithFormat:@"state_%ld", (long)state];
}

- (UIImage *)grayImage:(UIImage *)sourceImage {
    
    CGRect rect = CGRectMake(0, 0, sourceImage.size.width, sourceImage.size.height);
    
    UIGraphicsBeginImageContextWithOptions(rect.size, NO, sourceImage.scale);
    
    CGContextRef c = UIGraphicsGetCurrentContext();
    
    [sourceImage drawInRect:rect];
    
    CGContextSetFillColorWithColor(c, [UIColor colorWithRed:0 green:0 blue:0 alpha:.4].CGColor);
    
    CGContextSetBlendMode(c, kCGBlendModeSourceAtop);
    
    CGContextFillRect(c, rect);
    
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    
    UIGraphicsEndImageContext();
    
    return result;
}

//////////////////////////////////////////////

+ (ARButton *)buttonWithFrame:(CGRect)frame {
    
    ARButton *btn = [ARButton buttonWithType:UIButtonTypeCustom];
    [btn setFrame:frame];
    btn.titleRect = CGRectMake(0, 0, frame.size.width, frame.size.height);
    btn.imageRect = CGRectMake(0, 0, frame.size.width, frame.size.height);
    btn.backgroundRect = CGRectMake(0, 0, frame.size.width, frame.size.height);
    
    return btn;
}


+ (ARButton *)buttonWithFrame:(CGRect)frame
                    titleRect:(CGRect)titleRect {
    
    ARButton *btn = [ARButton buttonWithType:UIButtonTypeCustom];
    [btn setFrame:frame];
    [btn setTitleRect:titleRect];
    [btn setBackgroundRect:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    
    return btn;
}


+ (ARButton *)buttonWithFrame:(CGRect)frame
                    imageRect:(CGRect)imageRect {
    
    ARButton *btn = [ARButton buttonWithType:UIButtonTypeCustom];
    [btn setFrame:frame];
    [btn setImageRect:imageRect];
    [btn setBackgroundRect:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    
    return btn;
}


+ (ARButton *)buttonWithFrame:(CGRect)frame
                    titleRect:(CGRect)titleRect
                    imageRect:(CGRect)imageRect {
    
    ARButton *btn = [ARButton buttonWithType:UIButtonTypeCustom];
    [btn setFrame:frame];
    [btn setImageRect:imageRect];
    [btn setTitleRect:titleRect];
    [btn setBackgroundRect:CGRectMake(0, 0, frame.size.width, frame.size.height)];
    
    return btn;
}


+ (ARButton *)buttonWithFrame:(CGRect)frame
                    titleRect:(CGRect)titleRect
                    imageRect:(CGRect)imageRect
               backgroundRect:(CGRect)backgroundRect {
    
    ARButton *btn = [ARButton buttonWithType:UIButtonTypeCustom];
    [btn setFrame:frame];
    [btn setTitleRect:titleRect];
    [btn setImageRect:imageRect];
    [btn setBackgroundRect:backgroundRect];
    
    return btn;
}

@end
